goog.provide('dkpoints.status.MessageGroup');

goog.require('dkpoints.status.Message');

goog.require('goog.dom');
goog.require('soy');



/**
 * A related group of status messages.
 * @param {string} groupName The display name of the group.
 * @param {Element} parentEl the parent element into which this group should be
 *    inserted.
 * @constructor
 */
dkpoints.status.MessageGroup = function(groupName, parentEl) {
  /**
   * A map of messageIDs to their Message instances.
   * @type {Object.<string, dkpoints.status.Message>}
   * @private
   */
  this.messageList_ = {};
  this.messageList_.count = 0;

  /**
   * @type {string}
   * @private
   */
  this.groupName_ = groupName;

  /**
   * @type {Element}
   * @private
   */
  this.parentEl_ = parentEl;

  /**
   * @type {Element}
   * @private
   */
  this.groupEl_ = soy.renderAsElement(dkpoints.status.templates.newGroup,
                                      {groupname: groupName});
};


/**
 * Add a message to the group.  Fails if a message with the same messageID
 * already exists.
 * @param {string} message The text of the message.
 * @param {string} messageID The ID of the message.
 * @return {boolean} True if the message was successfully added; false if not.
 */
dkpoints.status.MessageGroup.prototype.addMessage =
    function(message, messageID) {

  var messageList = this.messageList_;

  if (messageList[messageID]) {
    return false;
  }
  else {
    if (this.groupEl_.parentNode !== this.parentEl_) {
      this.parentEl_.appendChild(this.groupEl_);
    }

    var messageObj = null;
    this.messageList_[messageID] = messageObj =
        new dkpoints.status.Message(message, messageID, this.groupEl_);

    messageList.count++;
    return true;
  }
};


/**
 * Update an existing message.
 * @param {string} message The text of the message.
 * @param {string} messageID The ID of the message.
 * @return {boolean} True if the message was successfully updated; false if not.
 */
dkpoints.status.MessageGroup.prototype.updateMessage =
    function(message, messageID) {

  var messageObj = this.messageList_[messageID];
  if (goog.isDef(messageObj)) {
    return messageObj.updateMessage(message);
  }
  else {
    return false;
  }
};


/**
 * Remove an existing message.
 * @param {string} messageID The ID of the message to be removed.
 * @return {boolean} True if the message was removed; false if not.
 */
dkpoints.status.MessageGroup.prototype.removeMessage = function(messageID) {
  var messageList = this.messageList_,
      message = messageList[messageID];

  if (goog.isDef(message)) {
    message.dispose();
    delete messageList[messageID];
    messageList.count--;

    if (messageList.count === 0) {
      this.parentEl_.removeChild(this.groupEl_);
    }

    return true;
  }
  else {
    return false;
  }
};


/**
 * Remove all messages in the group.
 * @return {number} The number of messages removed.
 */
dkpoints.status.MessageGroup.prototype.dispose = function() {
  var removed = this.messageList_.count;

  this.messageList_ = null;

  if (this.groupEl_.parentNode === this.parentEl_) {
    this.parentEl_.removeChild(this.groupEl_);
  }

  this.groupEl_.innerHTML = '';
  this.groupEl_ = this.parentEl_ = null;

  return removed;
};


/**
 * @return {number} The number of messages currently being displayed.
 */
dkpoints.status.MessageGroup.prototype.getCount = function() {
  return this.messageList_.count || 0;
};
